From ce4eb12ffb69196242207e76bcc4ee5dcea0c6c2 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Thu, 2 Aug 2018 13:58:56 -0500 Subject: [PATCH] tests: Add tests for remote summary update races There have been subtle bugs in the past when a client pulls while the remote server is updating the summary. The client may get the old summary and new signature or vice versa. Add tests to simulate this behavior to make sure there aren't regressions in the future. Closes: #1698 Approved by: cgwalters --- tests/test-pull-summary-sigs.sh | 81 ++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/tests/test-pull-summary-sigs.sh b/tests/test-pull-summary-sigs.sh index c6d04f41..77ff8444 100755 --- a/tests/test-pull-summary-sigs.sh +++ b/tests/test-pull-summary-sigs.sh @@ -23,7 +23,7 @@ set -euo pipefail . $(dirname $0)/libtest.sh -echo "1..7" +echo "1..9" COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}" setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" @@ -151,4 +151,83 @@ grep static-deltas summary.txt > static-deltas.txt assert_file_has_content static-deltas.txt \ $(${OSTREE} --repo=repo rev-parse origin:main) +## Tests for handling of cached summaries while racing with remote summary updates + +# Make 2 different but valid summary/signature pairs to test races with +${OSTREE} --repo=${test_tmpdir}/ostree-srv/gnomerepo summary -u ${COMMIT_SIGN} +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary{,.1} +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{,.1} +mkdir ${test_tmpdir}/ostree-srv/even-another-files +cd ${test_tmpdir}/ostree-srv/even-another-files +echo 'hello world even another object' > even-another-hello-world +${OSTREE} --repo=${test_tmpdir}/ostree-srv/gnomerepo commit ${COMMIT_SIGN} -b even-another -s "A commit" -m "Another Commit body" +${OSTREE} --repo=${test_tmpdir}/ostree-srv/gnomerepo summary -u ${COMMIT_SIGN} +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary{,.2} +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{,.2} +cd ${test_tmpdir} + +# Reset to the old valid summary and pull to cache it +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary{.1,} +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.1,} +repo_reinit +${OSTREE} --repo=repo pull origin main +assert_has_file repo/tmp/cache/summaries/origin +assert_has_file repo/tmp/cache/summaries/origin.sig +cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2 +cmp repo/tmp/cache/summaries/origin.sig ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig.1 >&2 + +# Simulate a pull race where the client gets the old summary and the new +# summary signature since it was generated on the server between the +# requests +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.2,} +if ${OSTREE} --repo=repo pull origin main 2>err.txt; then + assert_not_reached "Successful pull with old summary" +fi +assert_file_has_content err.txt "none are in trusted keyring" +assert_has_file repo/tmp/cache/summaries/origin +assert_has_file repo/tmp/cache/summaries/origin.sig +cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2 +cmp repo/tmp/cache/summaries/origin.sig ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig.1 >&2 + +# Publish correct summary and check that subsequent pull succeeds +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary{.2,} +${OSTREE} --repo=repo pull origin main +assert_has_file repo/tmp/cache/summaries/origin +assert_has_file repo/tmp/cache/summaries/origin.sig +cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.2 >&2 +cmp repo/tmp/cache/summaries/origin.sig ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig.2 >&2 + +echo "ok pull with signed summary remote old summary" + +# Reset to the old valid summary and pull to cache it +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary{.1,} +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.1,} +repo_reinit +${OSTREE} --repo=repo pull origin main +assert_has_file repo/tmp/cache/summaries/origin +assert_has_file repo/tmp/cache/summaries/origin.sig +cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2 +cmp repo/tmp/cache/summaries/origin.sig ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig.1 >&2 + +# Simulate a pull race where the client gets the new summary and the old +# summary signature. This is unlikely to happen except if the web server +# is caching the old signature. This should succeed because the cached +# old summary is used. +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary{.2,} +${OSTREE} --repo=repo pull origin main +assert_has_file repo/tmp/cache/summaries/origin +assert_has_file repo/tmp/cache/summaries/origin.sig +cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2 +cmp repo/tmp/cache/summaries/origin.sig ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig.1 >&2 + +# Publish correct signature and check that subsequent pull succeeds +cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.2,} +${OSTREE} --repo=repo pull origin main +assert_has_file repo/tmp/cache/summaries/origin +assert_has_file repo/tmp/cache/summaries/origin.sig +cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.2 >&2 +cmp repo/tmp/cache/summaries/origin.sig ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig.2 >&2 + +echo "ok pull with signed summary remote old summary signature" + libtest_cleanup_gpg -- 2.30.2